﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;

namespace Simpletron
{
  public class ExecutionContext : IInput, IOutput, IMemoryDump
  {
    public Memory Memory { get; private set; }

    public int Counter { get; set; }
    
    public int InstructionRegister { get; set; }
    
    public int OperationCode { get; set; }
    
    public int Operand { get; set; }
    
    public int Accumulator { get; set; }

    public ExecutionState ExecutionState { get; set; }

    public ExecutionContext()
      : this(30000)
    { }

    public ExecutionContext(int memorySize)
    {
      Memory = Memory.CustomMemory(memorySize, 0);
      Counter = 0;
      InstructionRegister = 0;
      OperationCode = 0;
      Operand = 0;
      Accumulator = 0;
      ExecutionState = ExecutionState.Stopped;
    }

    public int GetOutput()
    {
      return Memory[Operand];
    }

    public void SetInput(int input)
    {
      //TODO Change ApplicationException to some Simpletron exception type.
      Memory[Operand] = input;
    }

    public void RaiseOutputAwaits()
    {
      if (RaiseOutputAwaitsDelegate != null) RaiseOutputAwaitsDelegate(this);
    }

    public void RaiseInputRequest()
    {
      if (RaiseInputRequestDelegate != null) RaiseInputRequestDelegate(this);
    }

    public void Dump(IMemoryDumpWriter writer)
    {
      Memory.Dump(writer);
    }

    internal Action<IOutput> RaiseOutputAwaitsDelegate;

    internal Action<IInput> RaiseInputRequestDelegate;
  }
}
